package com.tbi.graphcolouring;

import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class BaseGraph {
	private List<Node> nodes;
	private int size;
	private int numberOfColors;
	
	public BaseGraph(int size) {
		this.size = size;
		nodes = new ArrayList<>();
		
		for(int i=0; i<size; i++){
			nodes.add(new Node(i));
		}
	}
	
	public void addConnection(int nodeID, int connectedNodeID){
		nodeID--;connectedNodeID--;
		Node from = findNode(nodeID);
		Node to = findNode(connectedNodeID);
		
		if(from == null || to == null){
			throw new IllegalArgumentException("cannot find starting or ending node!");
		}
		
		if(!from.connections.contains(to)){
			from.connections.add(to);
		}
		if(!to.connections.contains(from)){
			to.connections.add(from);
		}
	}
	
	public void setUpColors(int[] colors){
		Set<Integer> colorCounter = new HashSet<>();
		for(Node n : nodes){
			n.color = colors[n.id];
			colorCounter.add(colors[n.id]);
		}
		this.numberOfColors = colorCounter.size();
	}
	
	public int[] getColors(){
		int[] colors = new int[size];
		for(Node n : nodes){
			colors[n.getID()] = n.getColor();
		}
		return colors;
	}
	
	public List<Node> getNodes() {
		return nodes;
	}
	
	public int getSize() {
		return size;
	}
	
	public int getNumberOfColors() {
		return numberOfColors;
	}
	
	private Node findNode(int nodeID){
		if(nodeID >= this.size){ return null; }
		for(Node n : nodes){
			if(n.getID() == nodeID)
				return n;
		}
		//this should never happen
		return null; 
	}
	
	public class Node{
		private List<Node> connections;
		private int id;
		private int color;
		
		public Node(int id) {
			this.id = id;
			connections = new ArrayList<>();
		}
		
		public int getID(){
			return id;
		}
		
		public int getColor() {
			return color;
		}
		
		public List<Node> getConnections() {
			return connections;
		}
		
		public void setColor(int color) {
			this.color = color;
		}
		
		@Override
		public boolean equals(Object obj) {
			if(obj == this) return true;
			if(obj == null) return false;
			if(obj.getClass() != Node.class) return false;
			
			Node n = (Node) obj;
			if(n.getID() != this.id) return false;
			
			return true;
		}
		
		@Override
		public int hashCode() {
			return id;
		}
	}
}
